package com.zhdl.modules.spacer.service;

import com.project.common.util.DelayUtil;
import com.zhdl.common.ytools.HexToBitTools;
import com.zhdl.hardware.plc.siemens.service.SiemensCmdSendService;
import com.zhdl.modules.tools.CommonCallback;
import com.zhdl.modules.tools.IntToHexUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

import static com.zhdl.modules.spacer.ProcessTest.plcIp;

@Slf4j
@Component
public class SpacerPlCControlService {
    @Resource
    SiemensCmdSendService siemensCmdSendService;
    @Resource
    public ThreadPoolTaskScheduler taskScheduler1;
    Map<String, ScheduledFuture<?>> mapSF = new HashMap<>();
    String siemensValue;

    /**
     * 穿垫片-读取plc信号
     */
    public void readPlcSignal(CommonCallback<String> callback){
        siemensCmdSendService.siemensAddressValue(plcIp, "0000", 128, 100, s -> {
            siemensValue = s;
            log.info("读取到的结果为" + s);
            callback.statusCallback(s);
        });
    }

    /**
     * 穿垫片-上料和下料开始信号
     */
    public void readUpAndDownSignal(CommonCallback<String> callback){
        String pickValue = HexToBitTools.readHexValueByAddress(siemensValue, "000E");
        String pickBitValue = HexToBitTools.readBitValueByHex(pickValue);
        log.info("当前HEX数据为:"+pickValue+",Bit数据为:"+pickBitValue);
        callback.statusCallback(pickBitValue);
    }
    public void runAbsLocation(int model, float speed, float distance){
        runAbsLocation(model,speed,distance,null);
    }
    public void runAbsLocation(int model, float speed, float distance, CommonCallback<Boolean> callback){
        String address = motorModelAddress(model);
        String hexAddressUp = hexAddressUp(address, 12);//设置绝对运动 速度
        siemensCmdSendService.siemensWriteValues(plcIp, hexAddressUp, IntToHexUtil.floatTo8hex(speed));
        String distanceAddressUp = hexAddressUp(address, 8);//设置绝对运动距离
        siemensCmdSendService.siemensWriteValues(plcIp, distanceAddressUp, IntToHexUtil.floatTo8hex(distance));
        String writeValueByBit = HexToBitTools.writeValueByBit("0000", 0, 1);
        siemensCmdSendService.siemensWriteValue(plcIp, address, writeValueByBit);
        String distanceRunUp = hexAddressUp(address, 6);//设置绝对运动距离
        String writeValueByBitFalse = HexToBitTools.writeValueByBit("0000", 0, 0);
        siemensCmdSendService.siemensWriteValue(plcIp, distanceRunUp, writeValueByBitFalse);
        siemensCmdSendService.siemensWriteValue(plcIp, distanceRunUp, writeValueByBit);
      //  readPlcMotorRunDone(model,callback);
    }
    public void runJog(int model, float speed){
        String address = motorModelAddress(model);
        String hexAddressUp = hexAddressUp(address, 18);//设置绝对运动 速度
        siemensCmdSendService.siemensWriteValues(plcIp, hexAddressUp, IntToHexUtil.floatTo8hex(speed));
    }
    public void runRelativeLocation(int model, float speed, float distance){
        runAbsLocation(model,speed,distance,null);
    }
    public void runRelativeLocation(int model, float speed, float distance, CommonCallback<String> callback){
        String address = motorModelAddress(model);
    }
    public void writePlcIO(int address,int bit,boolean open){
        int realAddress = address / 2;
        String hexAddress = IntToHexUtil.shortToHex(realAddress);
        if (address%2==1){
            bit += 8;
        }
        String hexValue = HexToBitTools.writeValueByBit("0000", bit, open ? 1 : 0);
        siemensCmdSendService.siemensWriteValue(plcIp, hexAddress, hexValue);
    }
    public void plcSetMotorReady(int model, int readyType, int value) {
        String address = motorModelAddress(model);
        if (address.isEmpty()) {
            return;
        }
        /* 0 绝对位置运动 0.1 相对位置运动 0.2 0.3 job 正向反向运动 */
        StringBuffer hexRun = new StringBuffer();
        if (readyType == 0) {
            hexRun.append(HexToBitTools.writeValueByBit("0000", 0, value));
        } else if (readyType == 1) {
            hexRun.append(HexToBitTools.writeValueByBit("0000", 1, value));
        }
        /* 设置安全位置 */
        StringBuffer safe = hexRun.replace(2, 4, "01");
        String hexValue = safe.toString();
        siemensCmdSendService.siemensWriteValue(plcIp, address, hexValue);
    }
    /**
     * PLC-读取电机是否运动到位
     *
     * @param model    电机编号
     * @param callback 回调
     */
    public void readPlcMotorRunDone(int model, CommonCallback<Boolean> callback) {
        String address = motorModelAddress(model);
        if (address.isEmpty()) {
            return;
        }
        /* 一直读取是否到位 */
        DelayUtil.delayedExecution(100, () -> {
            ScheduledFuture<?> scheduledFuture = taskScheduler1.scheduleWithFixedDelay(() -> {
                String hexAddressUp = hexAddressUp(address, 16);
                String valueByAddress = HexToBitTools.readHexValueByAddress(siemensValue, hexAddressUp);
                String bitByValue = HexToBitTools.readBitValueByHex(valueByAddress);
                String doneStatus = bitByValue.substring(0, 1);
                log.info("Motor-" + model + "-当前编号电机状态"+doneStatus) ;
                if (doneStatus.equals("1")) {
                    log.info("Motor-" + model + "-当前编号电机运动完成");
                    ScheduledFuture<?> scheduledFuture1 = mapSF.get("Motor编号" + model);
                    if (scheduledFuture1!=null){
                        scheduledFuture1.cancel(true);
                    }
                    callback.statusCallback(true);
                }
            }, 100);
            mapSF.put("Motor编号" + model, scheduledFuture);
        });
    }
    /**
     * 寄存器-地址变大操作
     *
     * @param hexAddress 十六进制寄存器地址
     * @param upNum      要增大的数字
     * @return 十六进制地址
     */
    public String hexAddressUp(String hexAddress, int upNum) {
        int addressDec = Integer.parseInt(hexAddress, 16);
        upNum = upNum / 2;
        addressDec = addressDec + upNum;
        return IntToHexUtil.shortToHex(addressDec);
    }

    /**
     * PLC-获取电机寄存器地址
     * 轴一 write 0-34 read 34-48
     *
     * @param model 电机型号
     * @return 寄存器地址
     */
    public String motorModelAddress(int model) {
        int addDec;
        if (model == 1){
            addDec = 7;
        }else{
            addDec = 7+(model-1)*13;
        }
        return IntToHexUtil.shortToHex(addDec);
    }
}
